
//namespace Layer
//{
//    using PointList = List<Vector3>;
//    [Serializable()]
//    public abstract class ROIBase : Drawable
//    {
//        //
//        // Properties
//        //
//        protected float sliceThickness;
//        protected float opacity; 
//        protected Boundary boundary;
//        protected Outline outline;
//        protected List<Vector4> clipPlanes;
//        protected bool showOutline;
//        protected bool showBoundary;
//        protected Matrix4 m_WorldToRoi; // transformation from world space to ROI's bounding box space
//        protected Matrix4 m_RoiToWorld; // transformation from ROI's bounding box to world space
//        protected Matrix4 m_TextureToRoi; // transformation from (volume) texture space to ROI's bbox space
//        protected Matrix4 m_RoiToTexture; // transformation from ROI's bbox space to (volume) texture space
//        protected int m_NumSlices; // number of slices inside the ROI object
//        protected Vector3 m_SliceDirection; // normalized slice advancing direction
//        protected bool m_IsRoiModified; // flag indicates whether ROI solid is modified
//        protected PointList m_Bounds; // point list of the inside ROI slice geometry in the current ROI soild object
        
//        //
//        // Main constructor
//        //
//        public ROIBase(String name)
//            : base(name)
//        {
//            InitializeDefaults();
//        }

//        public ROIBase(String name, BoundingBox boundingBox)
//            : base(name, boundingBox)
//        {
//            InitializeDefaults();
//        }

//        private void InitializeDefaults()
//        {
//            sliceThickness = 0.0061149f;
//            opacity = 0.5f;
//            this.Material.Compositor.Blending = OhioState.Graphics.BlendMode.OVER;
//            this.Material.Compositor.AlphaTest = OhioState.Graphics.AlphaMode.OFF;
//            BoundingBox boundaryBox = bBox as OhioStateCommon.BoundingBox;
//            boundary = new Boundary("Default Boundary", boundaryBox);
//            outline = new Outline("Default Outline", boundaryBox);
//            clipPlanes = new List<Vector4>();
//            showOutline = true;
//            showBoundary = false;

//            m_NumSlices = 0;
//            m_IsRoiModified = true;
//            SetSliceDirection(new Vector3(0.0f, 1.0f, 1.0f));
//            m_Bounds = new List<Vector3>();
            
//            // default transformation matrices
//            float scale = 1.0f;
//            float shift = 1.0f;

//            SetWorldToRoiMatrix(new Matrix4(
//                scale, 0.0f, 0.0f, shift,
//                0.0f, scale, 0.0f, shift,
//                0.0f, 0.0f, scale, shift,
//                0.0f, 0.0f, 0.0f, 1.0f ));
//            SetTextureToRoiMatrix(new Matrix4(
//                2.0f, 0.0f, 0.0f, 0.0f,
//                0.0f, 2.0f, 0.0f, 0.0f,
//                0.0f, 0.0f, 2.0f, 0.0f,
//                0.0f, 0.0f, 0.0f, 1.0f ));

//            boundary.AddChangedEventHandler(new IAssetManagedHandler(member_ChangedEvent));
//            outline.AddChangedEventHandler(new IAssetManagedHandler(member_ChangedEvent));
//        }

//        //
//        // Changed event - one of our members has changed, fire our changed event
//        //
//        private void member_ChangedEvent(IAssetManaged obj)
//        {
//            FireUpdateChangedEvent(this);
//        }

//        #region Public properties
        
//        //
//        // Public Properties
//        //
//        public Boundary Boundary
//        {
//            get { return boundary; }
//            set { boundary = value; }
//        }

//        public Outline Outline
//        {
//            get { return outline; }
//            set { outline = value; }
//        }

//        public bool ShowOutline
//        {
//            get { return showOutline; }
//            set { showOutline = value; }
//        }

//        public bool ShowBoundary
//        {
//            get { return showBoundary; }
//            set { showBoundary = value; }
//        }

//        public float SliceThickness
//        {
//            get { return sliceThickness; }
//            set {
//                float prevSliceThickness = sliceThickness;
//                sliceThickness = value;
//                //
//                // Calculate opacity based on slice thickness.
//                // Temporarily, the following is used and need to change to a smarter one later
//                //
//                if (sliceThickness > prevSliceThickness)
//                {
//                    opacity = 0.5f + (0.5f * (sliceThickness - prevSliceThickness) 
//                                         / (0.05f - prevSliceThickness));
//                }
//                else if (sliceThickness < prevSliceThickness)
//                {
//                    opacity = 0.5f - (0.3f * (prevSliceThickness - sliceThickness) 
//                                         / (prevSliceThickness - 0.001f));
//                }
//            }
//        }

//        public float Opacity
//        {
//            get { return opacity; }
//        }

//        public List<Vector4> ClipPlanes
//        {
//            get { return clipPlanes; }
//        }

//        public int NumSlices
//        {
//            get { return this.m_NumSlices; }
//            set { this.m_NumSlices = value; }
//        }

//        public bool IsROIModified
//        {
//            get { return m_IsRoiModified; }
//            set { m_IsRoiModified = value; }
//        }
//        #endregion

//        #region Accessors
//        public Vector3 GetSliceDirection()
//        {
//            return m_SliceDirection;
//        }

//        public void SetSliceDirection(Vector3 dir)
//        {
//            m_SliceDirection = Vector3.normalize(dir);
//        }

//        public PointList GetBoundPoints()
//        {
//            return m_Bounds;
//        }

//        public void SetBoundPoints(PointList bounds)
//        {
//            m_Bounds = bounds;
//        }

//        public void SetWorldToRoiMatrix(Matrix4 wld2roi)
//        {
//            m_WorldToRoi = wld2roi;
//            m_RoiToWorld = Matrix4.inverse(m_WorldToRoi);
//            m_IsRoiModified = true;
//        }

//        public Matrix4 GetWorldToRoiMatrix()
//        {
//            return m_WorldToRoi;
//        }

//        public void SetRoiToWorldMatrix(Matrix4 roi2wld)
//        {
//            m_RoiToWorld = roi2wld;
//            m_WorldToRoi = Matrix4.inverse(m_RoiToWorld);
//            m_IsRoiModified = true;
//        }

//        public Matrix4 GetRoiToWorldMatrix()
//        {
//            return m_RoiToWorld;
//        }

//        public void SetTextureToRoiMatrix(Matrix4 tex2roi)
//        {
//            m_TextureToRoi = tex2roi;
//            m_RoiToTexture = Matrix4.inverse(m_TextureToRoi);
//        }

//        public Matrix4 GetTextureToRoiMatrix()
//        {
//            return m_TextureToRoi;
//        }

//        public void SetRoiToTextureMatrix(Matrix4 roi2tex)
//        {
//            m_RoiToTexture = roi2tex;
//            m_TextureToRoi = Matrix4.inverse(m_RoiToTexture);
//        }

//        public Matrix4 GetRoiToTextureMatrix()
//        {
//            return m_RoiToTexture;
//        }
//        #endregion

//        //
//        // Set IsROIModified flag
//        //
//        public override void EndManipulation()
//        {
//            IsROIModified = true;
//            base.EndManipulation();
//        }

//}

    //
    // it contains some utility functions that help construct transformation matrices for ROI
    //
    //class ROIUtility
    //{
    //    public static Matrix4 ConstructWorldToRoiMatrix(BBox bbox)
    //    {
    //        Matrix4 rm = new Matrix4();
    //        Debug.Assert(bbox.V0[0] <= bbox.V1[0] && bbox.V0[1] <= bbox.V1[1] && bbox.V0[2] <= bbox.V1[2]);
    //        rm[0,3] = -bbox.V0[0];
    //        rm[1,3] = -bbox.V0[1];
    //        rm[2,3] = -bbox.V0[2];
    //        return rm;
    //    }

    //    public static Matrix4 ConstructRoiToTextureMatrix(BBox bbox)
    //    {
    //        Matrix4 rm = new Matrix4();
    //        Debug.Assert(bbox.V0[0] <= bbox.V1[0] && bbox.V0[1] <= bbox.V1[1] && bbox.V0[2] <= bbox.V1[2]);
    //        float sx, sy, sz;
    //        sx = bbox.V1[0] - bbox.V0[0];
    //        sy = bbox.V1[1] - bbox.V0[1];
    //        sz = bbox.V1[2] - bbox.V0[2];
    //        rm[0,0] = 1.0f / sx;
    //        rm[1,1] = 1.0f / sy;
    //        rm[2,2] = 1.0f / sz;
    //        return rm;
    //    }

    //    public static Matrix4 ConstructRoiToTextureMatrix(BBox bbox, BBox tex_brick)
    //    {
    //        Matrix4 rm = new Matrix4();
    //        Debug.Assert(bbox.V0[0] <= bbox.V1[0] && bbox.V0[1] <= bbox.V1[1] && bbox.V0[2] <= bbox.V1[2]);
    //        Debug.Assert(tex_brick.V0[0] <= tex_brick.V1[0] && tex_brick.V0[1] <= tex_brick.V1[1] &&
    //                     tex_brick.V0[2] <= tex_brick.V1[2]);
    //        float sx, sy, sz;
    //        sx = bbox.V1[0] - bbox.V0[0];
    //        sy = bbox.V1[1] - bbox.V0[1];
    //        sz = bbox.V1[2] - bbox.V0[2];
    //        float rx, ry, rz;
    //        rx = tex_brick.V1[0] - tex_brick.V0[0];
    //        ry = tex_brick.V1[1] - tex_brick.V0[1];
    //        rz = tex_brick.V1[2] - tex_brick.V0[2];
    //        rm[0,0] = 1.0f * rx / sx; rm[0,3] = tex_brick.V0[0];
    //        rm[1,1] = 1.0f * ry / sy; rm[1,3] = tex_brick.V0[1];
    //        rm[2,2] = 1.0f * rz / sz; rm[2,3] = tex_brick.V0[2];
    //        return rm;
    //    }
    //}
//}
